


import 'dart:convert';

import 'package:eciesdart/eciesdart.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:logger/logger.dart';
import 'package:xim/common/get_style_view.dart';
import 'package:xim/common/util/ecc.dart';
import 'package:xim/common/util/secp256.dart';
import 'package:xim/config/store_config.dart';
import 'package:xim/http/apis/user/user_api.dart';

class RegisterPageController extends GetxStateMixinController<void>{

  final log = Logger();

  /// 当前步骤
  int activeStep = 0;

  /// 是否已读
  var isReadMe = true;

  /// 是否开启了指纹登录
  var isUserFingerprint = true;

  /// 密码
  var password1 = "";

  /// 确认密码
  var password2 = "";

  /// 账号
  var account ="";

  /// 公钥
  var publicKey ="";

  /// 私钥
  var privateKey ="";

  /// pageController
  final pageController = PageController();

  /// 账号算法创建完成
  var createAccountStatus = AccountCreateStatus.notCreate;

  /// 助记词蒙版状态: true 显示， false：隐藏
  var showMnemonicStatus = false;

  /// 助记词
  List<String> mnemonic = [];

  /// curr  check mnemonic index
  var currCheckMnemonicIndex = 0;

  List<String> checkMnemonic = [];

  List<String> shuffleMnemonic = [];

  @override
  Future<void> dataInit() async {
    await createAccount();
  }

  updateUserFingerprintStatus(bool useFingerprintStatus){
    isUserFingerprint=useFingerprintStatus;
    update();
  }

  updateIsReadMe(bool? e){
    isReadMe = e??isReadMe;
    update();
  }

  /// 用户注册
  createAccount() async {
    // 生成助记词
    var mnemonic = EccUtil.generateMnemonic();
    var seed = EccUtil.mnemonicToSeed(mnemonic);
    var seedBigInt = EccUtil.bytesToBigInt(seed);
    var keyPair = EccUtil.generateKeyPair(seed: seedBigInt);

    this.mnemonic = mnemonic;
    checkMnemonic = List.generate(mnemonic.length, (index) => "");
    shuffleMnemonic =List.generate(mnemonic.length, (index) => mnemonic[index]);
    shuffleMnemonic.shuffle();
    publicKey = keyPair.publicKey;
    privateKey = keyPair.privateKey;

    // send register request
    var registerToken = await UserApi.requestUserLoginToken(hexPublicKey: publicKey);
    var plainTextRegisterToken = EccUtil.decryptHex(registerToken, keyPair.privateKey);
    var signToken = EccUtil.sign(plainTextRegisterToken, keyPair.privateKey);
    await UserApi.login(hexPubKey: publicKey, signToken: signToken);

    // store user info
    await StoreApi.instance.secureStoreUserMnemonic(mnemonic);
    await StoreApi.instance.secureStoreUserPublicKey(publicKey);
    await StoreApi.instance.secureStoreUserPrivateKey(privateKey);
  }



  updateActiveStep(int step){
    activeStep = step;
    pageController.jumpToPage(step);
    update();
  }

  updateAccountCreateStatus(AccountCreateStatus status){
    createAccountStatus = status;
    update();
  }

  updateShowMnemonicStatus(bool status){
    showMnemonicStatus = status;
    update();
  }

  updateCheckMnemonic(String data){
    if(isCheckedMnemonic(data)){
      deleteCheckMnemonicByData(data);
      return;
    }
    for(var i=0;i<checkMnemonic.length;i++){
      if(checkMnemonic[i].isEmpty){
        checkMnemonic[i] = data;
        break;
      }
    }
    update();
  }

  deleteCheckMnemonic(int index){
    checkMnemonic[index] = '';
    update();
  }
  deleteCheckMnemonicByData(String data){
    if(isCheckedMnemonic(data)){
      // delete
      var index = checkMnemonic.indexOf(data);
      deleteCheckMnemonic(index);
    }
  }

  isCheckedMnemonic(String data){
    return checkMnemonic.contains(data);
  }

  bool validCheckMnemonic(){
    for(var i=0;i<checkMnemonic.length;i++){
      if(checkMnemonic[i] != mnemonic[i]){
        return false;
      }
    }
    return true;
  }

  bool isFullCheckMnemonic(){
    return checkMnemonic
        .where((element) => element.isNotEmpty)
        .length == mnemonic.length;
  }


  bool isEmptyPassword(){
    return password1=='' || password2=='';
  }

  bool validCheckPassword(){
    return !isEmptyPassword()
        && password1!=password2;
  }

  void updatePassword1(String pwd){
    password1=pwd;
    update();
  }

  void updatePassword2(String pwd){
    password2=pwd;
    update();
  }

}

enum AccountCreateStatus {
  notCreate,
  hasCreate,
  showMnemonic,
  hasShowMnemonic,
  hasReCheckMnemonic,
  ;
}